<?php
/**
 * Created by JieHuiLong.
 * E-mail: jiehuilong@icloud.com
 * Date: 2016/8/16
 * Time: 16:00
 * 广告分组管理控制器
 */

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\DomainCreateRequest;
use App\Http\Requests\DomainUpdateRequest;
use App\Models\AdminUser as User;
use App\Models\Domain;
use App\Models\Domainame;
use App\Models\DomainAttributes as DomainAttr;
use App\Models\Group;
use App\Models\Templates;
use Cache;
use DB;
use Illuminate\Http\Request;

class DomainController extends Controller
{
    protected $fields = [
        'uid' => 1,
        'username' => '',
        'gid' => 0,
        'gname' => '',
        'domain' => '',
        'directory' => '',
        'go_to_type' => '',
        'go_to_type_title' => '',
        'target_gid' => 0,
        'target_gname' => '',
        'tpl_id' => 0,
        'template' => '',
		'access_type' => 'http',
    ];

	/**
	 * Display a listing of the resource.
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function index(Request $request)
	{
		// //缓存UserToken
		// $userToken = Cache::rememberForever('userToken', function () {
		// 	$tokenUid = auth()->user()->id;
		// 	$token = DB::table('tokens');
		// 	$userToken = $token->where('uid', '=', $tokenUid)->value('token');
		// 	if ($userToken === null) {
		// 		$userToken = $this->createToken($tokenUid);
		// 	}
		// 	return $userToken;
		// });
		if ($request->ajax()) {
			$data = array();
			$data['draw'] = $request->get('draw');
			$start = $request->get('start');
			$length = $request->get('length');
			$order = $request->get('order');
			$columns = $request->get('columns');
			$search = $request->get('search');
			$data['recordsTotal'] = Domain::where(session('authAdminCondition'))->count();
			$gid = $request->get('gid');
			$gidCondition = $gid ? [['gid', '=', $gid]] : [['gid', '>', 0]];
			if (strlen($search['value']) > 0) {
				$data['recordsFiltered'] = Domain::where(function ($query) use ($search) {
					$query->where('domain', 'LIKE', '%' . $search['value'] . '%')
						->orWhere('target', 'like', '%' . $search['value'] . '%');
				})->where(session('authAdminCondition'))->where($gidCondition)->count();

				$data['data'] = Domain::where(function ($query) use ($search) {
					$query->where('domain', 'LIKE', '%' . $search['value'] . '%')
						->orWhere('target', 'like', '%' . $search['value'] . '%');
				})->where(session('authAdminCondition'))->where($gidCondition)
					->skip($start)->take($length)
					->orderBy($columns[$order[0]['column']]['data'], $order[0]['dir'])
					->get();
			} else {
				$data['recordsFiltered'] = $data['recordsTotal'];
				$data['data'] = Domain::where(session('authAdminCondition'))->where($gidCondition)
					->skip($start)->take($length)
					->orderBy($columns[$order[0]['column']]['data'], $order[0]['dir'])
					->get();
			}
			return response()->json($data);
		}
		$data['groupId'] = $request->get('gid') ? $request->get('gid') : 0;
		return view('admin.domain.index', $data);
	}

	/**
	 * Show the form for creating a new resource.
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function create(Request $request)
	{
		$data = [];
		foreach ($this->fields as $field => $default) {
			$data[$field] = old($field, $default);
		}
		$data['gid'] = $request->gid ? (int)$request->gid : 0;
		$data['userList'] = User::lists('name', 'id');
		$data['groupList'] = Group::where(session('authAdminCondition'))->get();
		if(count($data['groupList'])==0)return redirect()->back()->withErrors("缺少分组！");
		foreach ($data['groupList'] as $key => $obj) {
			if ($obj->id == $data['gid']) {
				$data['groupList'][$key] = $data['groupList'][0];
				$data['groupList'][0] = $obj;
			}
		}
		return view('admin.domain.create', $data);
	}

	/**
	 * Store a newly created resource in storage.
	 *
	 * @param  \Illuminate\Http\Request $request
	 * @return \Illuminate\Http\Response
	 */
	public function store(DomainCreateRequest $request)
	{
		$userToken = Cache::rememberForever('userToken', function () {
            $tokenUid = auth()->user()->id;
            $token = DB::table('tokens');
            $userToken = $token->where('uid', '=', $tokenUid)->value('token');
            if ($userToken === null) {
                $userToken = $this->createToken($tokenUid);
            }
            return $userToken;
        });
        $domain = new Domain();
        $objDomainame = new Domainame;
        foreach (array_keys($this->fields) as $field) {
            $domain->$field = $request->get($field);
        }
        $domainList = str_replace("https://", '', $request->domain);
        $domainList = str_replace("http://", '', $domainList);
        $domainArr = preg_split('/\s+/', $domainList);
        foreach ($domainArr as $key => $value) {
            if (!count($domain->where('directory', $domain->directory)->where('domain', $value)->first())) {
				if(!$this->isDomain($value)){ //如果不是域名，直接报错
					return redirect('/admin/domain?gid=' . $domain->gid)->withErrors($value."不是域名!");
				}
                $domain->domain = $value;
                $domain->save();
				event(new \App\Events\userActionEvent('\App\Models\Domain',$domain->id, 1, '添加了域名['.$domain->domain.']' ));
				$this->crossUpTpl2($domain->id,$domain->tpl_id,$userToken);//更新模板

                //为每个域名添加基础的扩展属性
                $data['uid'] = $domain->uid;
                $data['username'] = $domain->username;
                $data['did'] = $domain->id;
                $data['domain'] = $domain->domain;
                $data['gid'] = $domain->gid;
                //添加基础属性
                $domainAttr = new DomainAttr();
                $domainAttr->addBaseAttr($data);
                $this->store($request);
            }
            //return redirect('/admin/domain?gid=' . $domain->gid)->withErrors($value . ' 域名已存在！');
        }
        
        return redirect('/admin/domain?gid=' . $domain->gid)->withSuccess('添加成功！');
    }


	/**
	 * Display the specified resource.
	 *
	 * @param  int $id
	 * @return \Illuminate\Http\Response
	 */
	public function show($id)
	{
		//
	}

	/**
	 * Show the form for editing the specified resource.
	 *
	 * @param  int $id
	 * @return \Illuminate\Http\Response
	 */
	public function edit(Request $request, $id)
	{
		/*$domain = Domain::find((int)$id);
		if (!$domain) return redirect('/admin/domain')->withErrors("找不到该域名!");
		foreach (array_keys($this->fields) as $field) {
			$data[$field] = old($field, $domain->$field);
		}
		$data['id'] = (int)$id;
		$data['gid'] = $request->gid ? (int)$request->gid : 0;
		$userList = User::lists('name', 'id');
		$data['userList'] = $userList;
		$data['groupList'] = Group::get();
		foreach ($data['groupList'] as $key => $obj){
			if($obj->id == $data['gid']){
				$data['groupList'][$key] =  $data['groupList'][0];
				$data['groupList'][0] =  $obj;
			}
		}
		return view('admin.domain.edit', $data);*/
		return redirect('/admin/domain');
	}

	/**
	 * Update the specified resource in storage.
	 *
	 * @param  \Illuminate\Http\Request $request
	 * @param  int $id
	 * @return \Illuminate\Http\Response
	 */
	public function update(DomainUpdateRequest $request, $id)
	{

		$domain = Domain::find((int)$id);
		foreach (array_keys($this->fields) as $field) {
			$domain->$field = $request->get($field);
		}
		$domain->save();
		$userToken = Cache::rememberForever('userToken', function () {
			$tokenUid = auth()->user()->id;
			$token = DB::table('tokens');
			$userToken = $token->where('uid', '=', $tokenUid)->value('token');
			if ($userToken === null) {
				$userToken = $this->createToken($tokenUid);
			}
			return $userToken;
		});
		$this->crossUpTpl2($domain->id,$domain->tpl_id,$userToken);//更新模板
        event(new \App\Events\userActionEvent('\App\Models\Domain',$id, 3, '更新域名['.$domain->domain.']'));
        return redirect('/admin/domain?did=' . $domain->id)->withSuccess('更新成功！');

	}
    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id or string ids=>1,2,3,4,5,6
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        if (is_numeric($id)) {
            $tag = Domain::find((int)$id);
            if ($tag) {
				$domain = $tag->domain;
                $tag->delete();
                DomainAttr::where('did', $id)->delete();
                DB::table('new_skins')->where('did', $id)->delete();
				event(new \App\Events\userActionEvent('\App\Models\Domain',$id, 2, '删除域名['.$domain.']'));
            } else {
                return redirect()->back()
                    ->withErrors("删除失败");
            }
        } else {
            $idArr = explode(',', $id);
			$domains = '';
			$ds = Domain::whereIn('id', $idArr)->get();
			foreach($ds as $d){ $domains.=$d->domain."、";}
            $recordRow = Domain::whereIn('id', $idArr)->delete();
            DomainAttr::whereIn('did', $idArr)->delete();
            DB::table('new_skins')->whereIn('did', $idArr)->delete();
			event(new \App\Events\userActionEvent('\App\Models\Domain',0, 2, '删除域名['.$domains.']'));
            if (!$recordRow) {
                return redirect()->back()
                    ->withErrors("删除失败");
            }
        }
        return redirect()->back()
            ->withSuccess("删除成功");
    }


	//更新模板
	public function upgradeTpl($id, $userToken, $tpl_id)
	{
		if (config('app.debug')) {
			return redirect()->back()
				->withErrors("请叫管理员禁用调试模式！不然无法正常更新模板！");
		}
		//获取域名信息
		$domain = Domain::find((int)$id);
		//获取域名属性
		$listsAttr = DomainAttr::where('did', $id)->get();
		$dataAttr = [];
		foreach ($listsAttr as $rowKey => $row) {
			$dataAttr[$row['call_tag']] = $row['value'];
		}
		//读取推广模板信息
		$sourceCode = htmlentities(Templates::where('id', $tpl_id)->value('source_code'));
		$sourceCode = $this->replaceTpLable($dataAttr, $sourceCode);
		//读取审核模板信息
		$sh_tpl_id = Group::where('id', $domain->gid)->value('sh_tpl_id');
		$sourceCodeCompany = htmlentities(Templates::where('id', $sh_tpl_id)->value('source_code'));
		$sourceCodeCompany = $this->replaceTpLable($dataAttr, $sourceCodeCompany);
		//把最新的模板保存到数据中
		$data['uid'] = $domain->uid;
		$data['username'] = $domain->username;
		$data['did'] = $domain->id;
		$data['gid'] = $domain->gid;
		$data['domain'] = $domain->domain;
		$data['html'] = $sourceCode;
		$time = time();
		$data['token'] = md5($userToken . $time);
		$newSkins = DB::table('new_skins');

		$newSkins->where('did', $domain->id)->delete();
		//保存推广模板
		$newSkins->insert($data);
		//保存审核模板
		$data['html'] = $sourceCodeCompany;
		$data['token'] = md5($data['token'] . $data['did']);
		$newSkins->insert($data);
		
        $data['directory']= $domain->directory;
        $callback = '/admin/domain?callback=' . $time;
        $callback .= '&did=' . $data['did'];
        $callback .= '&domain=' . $data['domain'];
        $callback .= '&directory=' . $domain->directory;
        $callback .= '&gid=' . $data['gid'];
        $url =  $domain->access_type.'://'.$domain->domain;
        $url .= "/upgrade.php";
		event(new \App\Events\userActionEvent('\App\Models\Domain',$id, 3, '更新域名['.$domain->domain.']的模板['.Templates::where('id', $tpl_id)->value('name').']生成到前台'));
        return redirect($callback)->withSuccess('更新模板成功！');
    }


	//重置Token
	public function resetToken($uid)
	{
		Cache::forget("userToken");
		$this->createToken($uid);
		return redirect('/admin/domain')->withSuccess('Token重置成功!');
	}

	public function createToken($uid)
	{
		$data['uid'] = $uid;
		$data['token'] = md5(csrf_token() . str_random(40) . time());
		$tokenObj = Db::table('tokens');
		$tokenObj->where('uid', $uid)->delete();
		$tokenObj->insert($data);
		return $data['token'];
	}

	protected function replaceTpLable($dataAttr, $sourceCode)
	{
		//循环替换模板标签属性
		foreach ($dataAttr as $key => $value) {
			$sourceCode = str_replace("{{" . $key . "}}", $value, $sourceCode);
		}
		$sourceCode = str_replace('{{$', "<?php echo \$data['", $sourceCode);
		$sourceCode = str_replace('$}}', "'];?>", $sourceCode);
		//清空不存在的值
		$sourceCode = preg_replace("/{{(.*?)}}/", '', $sourceCode);
		$sourceCode = html_entity_decode($sourceCode);
		return $sourceCode;
	}
		/*
		*域名启用和禁用
		*/
	public function setStatus(Request $request){
		$tag = Domain::find($request->id);
		if ($tag) {
			if($tag->status==1) {
				$tag->status=0;
				$tag->save();
				return response()->json(['status'=>200,'msg'=>'操作成功！','o'=>" <b>开启推广</b>",'c'=>'X-Small btn-xs text-danger']);
			}elseif($tag->status==0) {
				$tag->status=1;
				$tag->save();
				return response()->json(['status'=>200,'msg'=>'操作成功！','o'=>" <b>关闭推广</b>",'c'=>'X-Small btn-xs text-success']);
			}
		} else {
			return response()->json(['status'=>201,'msg'=>'操作失败！']);
		}
	}
	/**
	* @description 匹配
	*  t.cn 正确	t-.cn 错误	tt.cn正确	-t.cn 错误	t-t.cn 正确	tst-test-tst.cn 正确	tst--tt.cn -- 错误
	* @param $domain
	* @return bool
	*/
	public function isDomain($domain)
	{
		//^((https?|ftp|news):\/\/)?([a-z]([a-z0-9\-]*[\.。])+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$

		return !empty($domain) && strpos($domain, '--') === false &&
		//preg_match('/^([a-z0-9]+([a-z0-9-]*(?:[a-z0-9]+))?\.)?[a-z0-9]+([a-z0-9-]*(?:[a-z0-9]+))?(\.us|\.tv|\.org\.cn|\.org|\.net\.cn|\.net|\.mobi|\.me|\.la|\.info|\.hk|\.gov\.cn|\.edu|\.com\.cn|\.com|\.co\.jp|\.co|\.cn|\.cc|\.biz|\.top|\.club|\.name|\.museum|\.coop|\.aero)$/i', $domain) ? true : false;
			preg_match('/^([a-z]([a-z0-9\-]*[\.。])+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|top|cn|mobi|me|la|club|coop)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$/i', $domain) ? true : false;
	}
	//分组更新模板
	public function crossGUpTpl(Request $request){
		 if (config('app.debug')) {
			return redirect()->back()
				->withErrors("请叫管理员禁用调试模式！不然无法正常更新模板！");
		}  
			//缓存UserToken
		$userToken = Cache::rememberForever('userToken', function () {
			$tokenUid = auth()->user()->id;
			$token = DB::table('tokens');
			$userToken = $token->where('uid', '=', $tokenUid)->value('token');
			if ($userToken === null) {
				$userToken = $this->createToken($tokenUid);
			}
			return $userToken;
		});
		$hint="";//提示信息
		//$per=session()->get('per');//百分比
		$domains = session()->get('domains');//进度条更新，根据session来处理
		if(count($domains)==0){ //如果session里面数据等于0，则停止更新，返回更新完成
			session()->forget('domains');
			return ['status'=>200,"msg"=>"finish","hint"=>"执行完成！","count"=>session()->get('count'),"per"=>session()->get('per'),"domain"=>'完成'];
		}
		$c2 = "connet...";$status = 200;
		foreach($domains as $key=>$domain){
			$c2 = $this->crossUpTpl2($domain->id,$domain->tpl_id,$userToken);
			if($c2 == 'finish'){
				unset($domains[$key]);
			}else{
				$status = 201;
				$hint= $domain->domain;
				if($request->start=='toStart'){
					unset($domains[$key]);
					$status = 200;
				}
			}
			session()->forget('domains');
			$per = floor((1-count($domains)/session()->get('count'))*100);
			session(['domains'=>$domains,'per'=>$per]);
			break;
		}
		
		return ['status'=>$status,"msg"=>$hint,"count"=>(session()->get('count')-count($domains)),"per"=>session()->get('per'),"domain"=>$domain->domain];

	}

	public function crossUpTpl2($id,$tpl_id,$userToken){
		 if (config('app.debug')) {
			return redirect()->back()->withErrors("请叫管理员禁用调试模式！不然无法正常更新模板！");
		} 
        //获取域名信息
        $domain = Domain::find((int)$id);
        //获取域名属性
        $listsAttr = DomainAttr::where('did', $id)->get();
        $dataAttr = [];
        foreach ($listsAttr as $rowKey => $row) {
            $dataAttr[$row['call_tag']] = $row['value'];
        }
        //读取审核模板信息
        $sh_tpl_id = Group::where('id', $domain->gid)->value('sh_tpl_id');
        $sourceCodeCompany = htmlentities(Templates::where('id', $sh_tpl_id)->value('source_code'));
        $sourceCodeCompany = $this->replaceTpLable($dataAttr, $sourceCodeCompany);
        //把最新的模板保存到数据中
        $data['uid'] 		= $domain->uid;
        $data['username'] 	= $domain->username;
        $data['did'] 		= $domain->id;
        $data['gid'] 		= $domain->gid;
        $data['domain']		= $domain->domain;
		$time 				= time();
		$data['token'] 		= md5($userToken . $time);
		
        $url 				= $domain->access_type.'://'.$domain->domain."/upgrade.php";
		$newSkins = DB::table('new_skins');
		$newSkins->where('did', $domain->id)->delete();
		//保存审核模板
		$data['filename']	= 'company.php';//审核页文件名
        $data['html'] 		= $sourceCodeCompany;
        $data['term_id'] 	= Group::where('id',$domain->gid)->value('sh_term_id');
        $newSkins->insert($data);
		$data['directory']	= $domain->directory;
		$data['time'] 		= $time;
		$this->curlPost($url,$data);
		$data['token'] 		= md5($userToken . $time);
		//读取推广模板信息
		$tpl_ids = explode(',',$domain->tpl_id);
		$term_ids			= explode(',',Group::where('id',$domain->gid)->value('term_id'));//模板条件
		foreach($tpl_ids as $key=>$tpl_id){
			$temp				= Templates::where('id',$tpl_id)->value('source_code');
			unset($data['directory'],$data['time']);
			$data['filename']	= 'index'.($key+1).'.php';
			$data['html'] 		= $this->replaceTpLable($dataAttr,htmlentities($temp));
			$data['term_id'] 	= $term_ids[$key];
			$newSkins->insert($data);
			$data['directory']	= $domain->directory;
			$data['time'] 		= $time;
			if(httpcode($url)==200){
				event(new \App\Events\userActionEvent('\App\Models\Domain',$id, 3, '更新域名['.$domain->domain.']的模板'));
				$this->curlPost($url,$data);
			}else{
				return "error";
			}
		}
		return "finish";
	}
	///域名更新模板
	public function crossUpTpl(Request $request){
		$data['debug']=config('app.debug');
		$gid = $request->id;
		if(is_numeric($gid)){
			$domains = Domain::where('gid',$gid)->get();
		}else{
			$idArr = explode(',',$gid);
			$domains = Domain::whereIn('gid',$idArr)->get();
		}
		
		if(session()->has('domains')){
			session()->forget('domains');
		}
		session(['domains'=>$domains,'per'=>0,'count'=>count($domains)]);
		//$data['domains'] = session()->get('domains');
		$data['count'] = count($domains);
		return response()->json($data); 
	}
	public function curlPost($url,$data){
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		// post数据
		curl_setopt($ch, CURLOPT_POST, 1);
		// post的变量
		curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
		$output = curl_exec($ch);
		curl_close($ch);
		return $output;
	}
}